package com.youth.config.threadpool;

import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * @ClassName ExcelThreadPool
 * @Description: TODO excel线程池配置
 * @Author yjwu
 * @Date 2019/12/7 16:45
 **/
@Configuration
@Slf4j
public class ThreadPoolConfig {

    @Bean(name = "threadPoolTaskExecutor")
    public ThreadPoolTaskExecutor excelExecutor() {
        ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
        //核心线程数。线程池创建后不会立即创建线程，而是等待现成的到来。
        //如果当前执行的线程数大于该值，线程会加入到缓存队列。
        //如果当前线程池中的线程数量小于该值，即使线程池中的线程都是空闲状态，也会创建新的线程来处理添加进来的任务。
        //如果此时线程池中的数量等于核心线程数，但是缓冲队列未满，那么任务将被放入队列中。
        threadPoolTaskExecutor.setCorePoolSize(8);
        //最大线程数。
        //如果线程池中线程数大于核心线程数但是小于最大线程数，那么新的任务被放入队列中
        threadPoolTaskExecutor.setMaxPoolSize(8);
        //空闲线程最大存活时间。对超出核心线程数的那些线程起作用。
        threadPoolTaskExecutor.setKeepAliveSeconds(60);
        threadPoolTaskExecutor.setAllowCoreThreadTimeOut(true);
        //队列中最大任务数量
        threadPoolTaskExecutor.setQueueCapacity(4);
        //线程名称前缀
        threadPoolTaskExecutor.setThreadNamePrefix("ExcelThread-");
        //线程池拒绝策略。当达到最大线程数量后如何处理新任务。
        //AbortPolicy（默认），丢弃任务并且抛出RejectedExecutionException异常
        //DiscardPolicy，丢弃任务但是不抛出异常。
        //DiscardOldestPolicy，丢弃最早进入队列的任务，然后重新尝试执行新任务（重复执行此过程）
        //CallerRunsPolicy，由调用线程处理新任务，不会等待线程池中的线程去执行。
        threadPoolTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());
        //初始化线程池
        threadPoolTaskExecutor.initialize();

        log.info("threadPoolTaskExecutor initializing size=```" + threadPoolTaskExecutor.getActiveCount() + "," + threadPoolTaskExecutor.getCorePoolSize());
        return threadPoolTaskExecutor;

    }
}
